/*
 * statistic.c
 *
 *  Created on: 17 sept. 2013
 *      Author: the
 */
#include "statistic.h"

//Simulate and print on the standard output the results for the different metrics and for 'nbSamples' samples
//The standard output must have the following format:
//  #List the parameters here (as a comment): nbSamples, nbOfNodes, nbOfFrequencies, Algorithm, etc.
//  #--------------------------------------------------------------------------------------
//  # metric0 stdDeviation metric1 stdDeviation metric2 stdDeviation etc.
//  and the results here
void simulate(int Algorithm, int variantTopology, int nbSamples)
{
	int i=0, j, k, nbValSamples=0, node1, node2, pcr, mpi, tmp, connex;
	double moyPCR=0.0, moyMPI=0.0, varPCR=0.0, varMPI=0.0, moyConflict=0.0, varConflict=0.0, conflict, usage;
	double *statUsageFreq, *varUsageFreq;

	//Initialisation du tableau d'usage des frequences
	if((statUsageFreq=(double *) malloc(maxFreq*sizeof(double)))==NULL){
		fprintf(stderr,"Erreur simulate(): malloc statUsageFreq a echoue\n");
		exit(1);
	}
	if((varUsageFreq=(double *) malloc(maxFreq*sizeof(double)))==NULL){
		fprintf(stderr,"Erreur simulate(): malloc statUsageFreq a echoue\n");
		exit(1);
	}
	for(i=0;i<maxFreq;i++){
		statUsageFreq[i]=0.0; varUsageFreq[i]=0.0;
	}


	//Debut des simulations
	i=0;
	while(i<nbSamples){
		initArrayNodes(variantTopology);
		updateRoutingTable1AllNodes();//does not depend on frequency but only on nodes' location.

		//Verification de la connexite du reseau
		j=1; connex=1;
		while((j<nbOfNodes)&&(connex)){
			if(nodes[0].routingTable[j].destination==-1){
				//fprintf(stderr,"Erreur: le reseau n'est pas connexe\n");
				connex=0;
			}
			j++;
		}

		if(connex){

			//if(i%100==0) fprintf(stderr,"Algo %d echantillon %d sur %d\n",Algorithm,i,nbSamples);


			switch(Algorithm){
				case 1:	allocateFrequencyGreedy();
					break;
				case 2: allocateFrequencyTabu();
					break;
				case 3: allocateFrequencyMcair();
					break;
				case 4: //computeOptimal(variantAlgo);
					break;
				default:
					fprintf(stderr,"Bad value of Algorithm (must be in [1-4]\n");
					exit(2);
			}

			selectTwoNodes(&node1, &node2);

			pcr=pathCapacityReduction(node1,node2);
			mpi=maximumPathInterference(node1, node2);

			tmp=conflictGraphCommonChannel();

			moyPCR+=1.0*pcr; varPCR+=1.0*pcr*pcr;
			moyMPI+=1.0*mpi; varMPI+=1.0*mpi*mpi;
			if(tmp>0){
				//For the optimal (algo 6: no common channel), the computation is different
				if(Algorithm==6) conflict=1.0*minConflict/(1.0*tmp);
				else if(nbOfRadios>1) conflict=1.0+1.0*conflictGraph(1)/(1.0*tmp);
				else conflict=1.0;
			}
			moyConflict+=1.0*conflict; varConflict+=1.0*conflict*conflict;
			nbValSamples++;

			//Mise a jour de l'usage des frequences
			for(j=0;j<maxFreq;j++){
				usage=0.0;
				//Compte le nombre de noeuds utilisant cette frequences
				for(k=0;k<nbOfNodes;k++){
					if(usedfreq(k,j)>=0) usage+=1.0;
				}
				//On multiplie par 100 car c'est un pourcentage
				usage=100.0*usage/(1.0*nbOfNodes);
				statUsageFreq[j]+=usage;
				varUsageFreq[j]+=usage*usage;
			}

			//DEBUG
			//printArrayNodes();
			if(i==0) dessineGraph();//We plot the topology for the first sample
			i++;
		}//if(connex)
		freeNodes();
	}//end of while

	if(nbValSamples==0){
		fprintf(stderr,"Pas d'echantillon valide\n");
		return;
	}

	//Normalisation des tableaux d'usage des frequences
	for(j=0;j<maxFreq;j++){
		statUsageFreq[j]=statUsageFreq[j]/(1.0*nbSamples);
		varUsageFreq[j]=varUsageFreq[j]/(1.0*nbSamples);
		varUsageFreq[j]=varUsageFreq[j]-statUsageFreq[j]*statUsageFreq[j];

		//DEBUG
		if(j==0) fprintf(stderr,"Usage Freq 0=%f\n",statUsageFreq[0]);
	}

	moyPCR=moyPCR/(1.0*nbValSamples); varPCR=varPCR/(1.0*nbValSamples)-moyPCR*moyPCR;
	moyMPI=moyMPI/(1.0*nbValSamples); varMPI=varMPI/(1.0*nbValSamples)-moyMPI*moyMPI;
	moyConflict=moyConflict/(1.0*nbValSamples); varConflict=varConflict/(1.0*nbValSamples)-moyConflict*moyConflict;
	//Sometimes varConflict=-0.0000 (and the sqrt() does not like that).
	if(moyConflict<=0.0) moyConflict=0.0;
	if(varConflict<=0.0) varConflict=0.0;

	fprintf(stderr,"Algorithm %d nbSamples=%d nbOfNodes=%d Topology=%d (0=random 1=grid) nbRadio=%d nbFreq=%d\n",Algorithm,nbSamples,nbOfNodes,variantTopology,nbOfRadios,maxFreq);
	//Attention: pour un nombre d'echantillon =1 on peut avoir des "nan" du a des valeurs =-0.0000 pour la variance.
	fprintf(stderr,"#PCR Confident-interval(95%%) MPI Confident-interval(95%%) ConflictGraph(Fractional Network Interference) Confident-interval(95%%)");
	fprintf(stderr," -- Usage des frequences: Freq_0 (Conf Int: 2 cols) Freq_1 (Conf Int: 2 cols) etc.\n");
	printf("%f %f %f ",moyPCR,moyPCR-1.96*sqrt(varPCR)/(sqrt(1.0*nbValSamples)),moyPCR+1.96*sqrt(varPCR)/(sqrt(1.0*nbValSamples)));
	printf("%f %f %f ",moyMPI,moyMPI-1.96*sqrt(varMPI)/(sqrt(1.0*nbValSamples)),moyMPI+1.96*sqrt(varMPI)/(sqrt(1.0*nbValSamples)));
	printf("%f %f %f ",moyConflict,moyConflict-1.96*sqrt(varConflict)/(sqrt(1.0*nbValSamples)),moyConflict+1.96*sqrt(varConflict)/(sqrt(1.0*nbValSamples)));
	for(j=0;j<maxFreq;j++) printf("%f %f %f ",statUsageFreq[j],statUsageFreq[j]-1.96*sqrt(varUsageFreq[j])/sqrt(1.0*nbSamples),statUsageFreq[j]+1.96*sqrt(varUsageFreq[j])/sqrt(1.0*nbSamples));
	printf("\n");


	free(statUsageFreq); free(varUsageFreq);
}

